home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / aminet / dev / misc / dialoglib.lha / cycle.c < prev    next >
C/C++ Source or Header  |  1993-03-07  |  7KB  |  294 lines

  1. #include <libraries/gadtools.h>
  2. #include <graphics/text.h>
  3. #include <proto/diskfont.h>
  4. #include <proto/gadtools.h>
  5. #include <proto/graphics.h>
  6. #include <proto/intuition.h>
  7. #include <proto/utility.h>
  8. #include <string.h>
  9. #include <ctype.h>
  10. #include "dialog.h"
  11. #ifdef DEBUG1
  12.     #include <stdio.h>
  13. #endif
  14.  
  15. static LONG countChoices( DialogElement *de )
  16. {
  17.     LONG count = 0;
  18.     STRPTR *label;
  19.  
  20.     if( !de )
  21.         return 0;
  22.  
  23.     if( label = (STRPTR *)GetTagData( GTCY_Labels, 0, de->taglist ) )
  24.         while( *label++ )
  25.             count++;
  26.     return count;
  27. }
  28.  
  29. static ULONG getCycleStructure( DialogElement *de )
  30. {
  31.     ULONG place, structure = DESF_HBaseline;
  32.  
  33.     if( !de )
  34.         return 0;
  35.  
  36.     if( GetTagData( NGDA_GadgetText, 0, de->taglist ) )
  37.     {
  38.         place = getTextPlacement( GetTagData( NGDA_Flags, 0, de->taglist ), PLACETEXT_LEFT );
  39.         switch( place )
  40.         {
  41.         case PLACETEXT_LEFT:
  42.         case PLACETEXT_RIGHT:
  43.             structure |= DESF_VBaseline;
  44.             break;
  45.         }
  46.     }
  47.     return structure;
  48. }
  49.  
  50. static VOID setupCycle( DialogElement *de )
  51. {
  52.     struct TextExtent te;
  53.     struct RastPort rp;
  54.     struct TextAttr *ta;
  55.     struct TextFont *tf;
  56.     STRPTR text, *label;
  57.     ULONG place;
  58.     LONG width, top, bottom, textwidth, texttop, textbottom;
  59.     LONG *storage;
  60.  
  61.     if( !de )
  62.         return;
  63.  
  64.     de->idcmp_mask |= CYCLEIDCMP | IDCMP_REFRESHWINDOW | IDCMP_VANILLAKEY;
  65.  
  66.     storage = (LONG *)GetTagData( DA_Storage, 0, de->taglist );
  67.     if( storage )
  68.         *storage = GetTagData( GTCY_Active, 0, de->taglist );
  69.  
  70.     ta = (struct TextAttr *)GetTagData( NGDA_TextAttr, 0, de->taglist );
  71.     if( !ta )
  72.         return;
  73.     tf = OpenDiskFont( ta );
  74.     if( !tf )
  75.         return;
  76.     InitRastPort( &rp );
  77.     SetFont( &rp, tf );
  78.  
  79.     top = 2 + tf->tf_Baseline;
  80.     bottom = 2 + tf->tf_YSize - tf->tf_Baseline;
  81.     width = 0;
  82.     if( label = (STRPTR *)GetTagData( GTCY_Labels, 0, de->taglist ) )
  83.         while( *label )
  84.         {
  85.             LONG labwidth, labtop, labbottom;
  86.  
  87.             TextExtent( &rp, *label, strlen( *label ), &te );
  88.             labwidth = te.te_Extent.MaxX + 1 - te.te_Extent.MinX;
  89.             labtop = - te.te_Extent.MinY;
  90.             labbottom = te.te_Extent.MaxY + 1;
  91.             if( labwidth > width )
  92.                 width = labwidth;
  93.             if( labtop > top )
  94.                 top = labtop;
  95.             if( labbottom > bottom )
  96.                 bottom = labbottom;
  97.             label++;
  98.         }
  99.     width += 28;    /* add some space for the cycle glyph and border */
  100.  
  101.     text = (STRPTR)GetTagData( NGDA_GadgetText, 0, de->taglist );
  102.     place = getTextPlacement( GetTagData( NGDA_Flags, 0, de->taglist ), PLACETEXT_LEFT );
  103.  
  104.     if( text )
  105.         TextExtent( &rp, text, strlen( text ), &te );
  106.     else
  107.     {
  108.         te.te_Extent.MinX = te.te_Extent.MinY = 0;
  109.         te.te_Extent.MaxX = te.te_Extent.MaxY = -1;
  110.     }
  111.  
  112.     CloseFont( tf );
  113.  
  114.     textwidth = te.te_Extent.MaxX + 1 - te.te_Extent.MinX;
  115.     texttop = - te.te_Extent.MinY;
  116.     textbottom = te.te_Extent.MaxY + 1;
  117.  
  118.     switch( place )
  119.     {
  120.     case PLACETEXT_ABOVE:
  121.         if( width < textwidth )
  122.             width = textwidth;
  123.         setMinWidth( de, width );
  124.         setMaxWidth( de, MAX_SPACE );
  125.         setMinTopExtent( de, texttop + textbottom + INTERHEIGHT );
  126.         setMaxTopExtent( de, texttop + textbottom + INTERHEIGHT );
  127.         setMinBottomExtent( de, top + bottom );
  128.         setMaxBottomExtent( de, top + bottom );
  129.         break;
  130.     case PLACETEXT_BELOW:
  131.         if( width < textwidth )
  132.             width = textwidth;
  133.         setMinWidth( de, width );
  134.         setMaxWidth( de, MAX_SPACE );
  135.         setMinTopExtent( de, top + bottom );
  136.         setMaxTopExtent( de, top + bottom );
  137.         setMinBottomExtent( de, texttop + textbottom + INTERHEIGHT );
  138.         setMaxBottomExtent( de, texttop + textbottom + INTERHEIGHT );
  139.         break;
  140.     case PLACETEXT_LEFT:
  141.         if( top < texttop )
  142.             top = texttop;
  143.         if( bottom < textbottom )
  144.             bottom = textbottom;
  145.         setMinLeftExtent( de, textwidth + INTERWIDTH  );
  146.         setMaxLeftExtent( de, textwidth + INTERWIDTH  );
  147.         setMinRightExtent( de, width );
  148.         setMaxRightExtent( de, MAX_SPACE );
  149.         setMinTopExtent( de, top );
  150.         setMaxTopExtent( de, top );
  151.         setMinBottomExtent( de, bottom );
  152.         setMaxBottomExtent( de, bottom );
  153.         break;
  154.     case PLACETEXT_RIGHT:
  155.         if( top < texttop )
  156.             top = texttop;
  157.         if( bottom < textbottom )
  158.             bottom = textbottom;
  159.         setMinLeftExtent( de, width );
  160.         setMaxLeftExtent( de, MAX_SPACE );
  161.         setMinRightExtent( de, textwidth + INTERWIDTH );
  162.         setMaxRightExtent( de, textwidth + INTERWIDTH );
  163.         setMinTopExtent( de, top );
  164.         setMaxTopExtent( de, top );
  165.         setMinBottomExtent( de, bottom );
  166.         setMaxBottomExtent( de, bottom );
  167.         break;
  168.     case PLACETEXT_IN:
  169.         if( width < textwidth )
  170.             width = textwidth;
  171.         if( top < texttop )
  172.             top = texttop;
  173.         if( bottom < textbottom )
  174.             bottom = textbottom;
  175.         setMinWidth( de, width );
  176.         setMaxWidth( de, MAX_SPACE );
  177.         setMinTopExtent( de, top );
  178.         setMaxTopExtent( de, top );
  179.         setMinBottomExtent( de, bottom );
  180.         setMaxBottomExtent( de, bottom );
  181.         break;
  182.     }
  183. }
  184.  
  185. static ULONG layoutCycle( DialogElement *de, LayoutMessage *lm )
  186. {
  187.     struct NewGadget ng;
  188.     ULONG error = DIALOGERR_OK;
  189.  
  190.     if( !de )
  191.         return DIALOGERR_BAD_ARGS;
  192.     if( !lm )
  193.         return DIALOGERR_BAD_ARGS;
  194.  
  195. #ifdef DEBUG1
  196.     printf(
  197.     "layoutCycle : x %d, y %d, width %d, height %d, left %d, right %d, top %d, bottom %d\n",
  198.         lm->lm_X, lm->lm_Y, lm->lm_Width, lm->lm_Height,
  199.         lm->lm_Left, lm->lm_Right, lm->lm_Top, lm->lm_Bottom );
  200. #endif
  201.     ng.ng_GadgetText = (UBYTE *)GetTagData( NGDA_GadgetText, 0, de->taglist );
  202.     ng.ng_TextAttr = (struct TextAttr *)GetTagData( NGDA_TextAttr, 0, de->taglist );
  203.     ng.ng_VisualInfo = (APTR)GetTagData( NGDA_VisualInfo, 0, de->taglist );
  204.     ng.ng_Flags = GetTagData( NGDA_Flags, 0, de->taglist );
  205.     layoutGTSingleLined( &ng, lm, PLACETEXT_LEFT );
  206.     de->object = CreateGadgetA( CYCLE_KIND, *lm->lm_PreviousPtr, &ng, de->taglist );
  207.     *lm->lm_PreviousPtr = de->object;    /* advance "previous" pointer to new object */
  208.     if( !de->object )
  209.         error = DIALOGERR_NO_MEMORY;
  210.     return error;
  211. }
  212.  
  213. static DialogElement *matchCycle( DialogElement *de, MatchMessage *mm )
  214. {
  215.     struct IntuiMessage *imsg;
  216.     DialogElement *match = NULL;
  217.     struct TagItem *tag;
  218.     LONG *storage;
  219.  
  220.     if( !de )
  221.         return NULL;
  222.     if( !mm )
  223.         return NULL;
  224.  
  225.     storage = (LONG *)GetTagData( DA_Storage, 0, de->taglist );
  226.  
  227.     imsg = mm->mm_IntuiMsg;
  228.     switch( imsg->Class )
  229.     {
  230.     case IDCMP_GADGETUP:
  231.         if( de->object == imsg->IAddress )
  232.         {
  233.             if( storage )
  234.                 *storage = (ULONG)imsg->Code;        /* store current level */
  235.             match = de;
  236.         }
  237.         break;
  238.     case IDCMP_VANILLAKEY:
  239.         if( storage )
  240.             if( tag = FindTagItem( DA_EquivalentKey, de->taglist ) )
  241.                 if( imsg->Code == tolower( tag->ti_Data ) )
  242.                 {
  243.                     if( *storage < countChoices( de ) - 1 )
  244.                         (*storage)++;
  245.                     else
  246.                         *storage = 0;
  247.                     GT_SetGadgetAttrs( de->object, imsg->IDCMPWindow, NULL,
  248.                         GTCY_Active, *storage,
  249.                         TAG_DONE );
  250.                     match = de;
  251.                 }
  252.                 else if( imsg->Code == toupper( tag->ti_Data ) )
  253.                 {
  254.                     if( *storage > 0 )
  255.                         (*storage)--;
  256.                     else
  257.                         *storage = countChoices( de ) - 1;
  258.                     GT_SetGadgetAttrs( de->object, imsg->IDCMPWindow, NULL,
  259.                         GTCY_Active, *storage,
  260.                         TAG_DONE );
  261.                     match = de;
  262.                 }
  263.         break;
  264.     }
  265.     return match;
  266. }
  267.  
  268. ULONG dispatchCycle( struct Hook *hook, DialogElement *de, DialogMessage *dm )
  269. {
  270.     ULONG result;
  271.  
  272.     switch( dm->dm_MethodID )
  273.     {
  274.     case DIALOGM_GETSTRUCT:
  275.         result = getCycleStructure( de );
  276.         break;
  277.     case DIALOGM_SETUP:
  278.         setupCycle( de );
  279.         break;
  280.     case DIALOGM_LAYOUT:
  281.         result = layoutCycle( de, (LayoutMessage *)dm );
  282.         break;
  283.     case DIALOGM_MATCH:
  284.         result = (ULONG)matchCycle( de, (MatchMessage *)dm );
  285.         break;
  286.     case DIALOGM_CLEAR:
  287.         break;
  288.     case DIALOGM_SETATTRS:
  289.         setGTAttrs( de, (SetAttrsMessage *)dm );
  290.         break;
  291.     }
  292.     return result;
  293. }
  294.